Este trabajo tendrá el objetivo de visualizar el total de delitos ocurridos en cada barrio de la ciudad de Buenos Aires en el año 2021 y obtener, además, los días de la semana en que mayor ocurren según el tipo registrado.
Esto sirve para poder conectar mi proyecto generado en R con el repositorio online.
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.2 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ ggplot2 3.4.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.0
## ✔ purrr 1.0.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(sf)
## Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE
library(dplyr)
library(readr)
library(geoAr)
library(ggmap)
## The legacy packages maptools, rgdal, and rgeos, underpinning the sp package,
## which was just loaded, will retire in October 2023.
## Please refer to R-spatial evolution reports for details, especially
## https://r-spatial.org/r/2023/05/15/evolution4.html.
## It may be desirable to make the sf package available;
## package maintainers should consider adding sf to Suggests:.
## The sp package is now running under evolution status 2
## (status 2 uses the sf package in place of rgdal)
## ℹ Google's Terms of Service: <https://mapsplatform.google.com>
## ℹ Please cite ggmap if you use it! Use `citation("ggmap")` for details.
library(geofacet)
library(leaflet)
barrios_caba <- st_read("data/barrios_caba/barrios_caba.shp",
stringsAsFactors = TRUE,
options = "ENCODING=latin1")
## options: ENCODING=latin1
## Reading layer `barrios_caba' from data source
## `/Users/jimuberezovsky/Documents/RSTUDIO/TF/TF_BEREZOVSKY/data/barrios_caba/barrios_caba.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 48 features and 3 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -58.53152 ymin: -34.70529 xmax: -58.33515 ymax: -34.52649
## Geodetic CRS: WGS 84
delitos <- read.csv2("data/delitos_2021.csv",
stringsAsFactors = TRUE,
encoding="latin1")
dim(delitos)
## [1] 87390 11
Este dataset cuenta con 87.390 registros y 11 columnas/variables. Ellas son:
names(delitos)
## [1] "id.mapa" "fecha" "franja" "tipo" "subtipo" "uso_armas"
## [7] "barrio" "comuna" "latitud" "longitud" "cantidad"
summary(delitos)
## id.mapa fecha franja
## RH-2021-1000831: 2 6/11/21 : 390 19 : 5151
## RH-2021-1001062: 2 17/12/21: 360 18 : 5080
## RH-2021-1001914: 2 10/12/21: 342 12 : 4845
## RH-2021-1001945: 2 7/12/21 : 341 20 : 4792
## RH-2021-1002368: 2 29/11/21: 332 17 : 4773
## RH-2021-1003029: 2 21/12/21: 328 8 : 4752
## (Other) :87378 (Other) :85297 (Other):57997
## tipo subtipo uso_armas
## Homicidio : 192 :71631 :78992
## Hurto (sin violencia):36159 Con uso de moto: 4588 Arma cortante: 2481
## Lesiones : 6589 Doloso : 84 Arma de fuego: 5917
## Robo (con violencia) :44450 Femicidio : 14
## Hurto Automotor: 3666
## Robo Automotor : 724
## Siniestro Vial : 6683
## barrio comuna latitud longitud
## Palermo : 7785 Min. : 1.000 Min. :-34.70 Min. :-58.53
## Balvanera: 5952 1st Qu.: 4.000 1st Qu.:-34.63 1st Qu.:-58.47
## Flores : 4842 Median : 7.000 Median :-34.61 Median :-58.44
## Recoleta : 4397 Mean : 7.583 Mean :-34.61 Mean :-58.44
## Caballito: 4046 3rd Qu.:12.000 3rd Qu.:-34.59 3rd Qu.:-58.40
## Almagro : 3590 Max. :15.000 Max. :-34.53 Max. :-58.34
## (Other) :56778
## cantidad
## Min. : 1.00
## 1st Qu.: 1.00
## Median : 1.00
## Mean : 1.16
## 3rd Qu.: 1.00
## Max. :10.00
## NA's :80609
Podemos observar que: El tipo de delito más registrado durante 2021 fue el Robo (con violencia). El barrio donde más delitos se registraron fue Palermo.
str(delitos$fecha)
## Factor w/ 365 levels "1/1/21","1/10/21",..: 312 57 312 167 182 300 102 28 218 324 ...
Cambiaremos los registors a formato “fecha”, para poder operar con esa columna:
delitos<- delitos %>%
mutate(fecha=dmy(fecha))
str(delitos$fecha)
## Date[1:87390], format: "2021-04-05" "2021-06-13" "2021-04-05" "2021-08-21" "2021-10-23" ...
Efectivamente, ahora el campo fecha dejó de ser factor y pasó a ser “Date” Ahora, agregamos 2 nuevas columnas a nuestro dataset donde indicamos el mes y el día de la semana en que ocurrió cada registro:
delitos<- delitos %>%
mutate(mes=month(fecha, label = TRUE, abbr=FALSE, locale="es_ES.UTF-8"),
dia_semana=wday(fecha, label=TRUE, abbr=FALSE, locale="es_ES.UTF-8"))
summary(delitos)
## id.mapa fecha franja
## RH-2021-1000831: 2 Min. :2021-01-01 19 : 5151
## RH-2021-1001062: 2 1st Qu.:2021-03-31 18 : 5080
## RH-2021-1001914: 2 Median :2021-07-13 12 : 4845
## RH-2021-1001945: 2 Mean :2021-07-07 20 : 4792
## RH-2021-1002368: 2 3rd Qu.:2021-10-12 17 : 4773
## RH-2021-1003029: 2 Max. :2021-12-31 8 : 4752
## (Other) :87378 (Other):57997
## tipo subtipo uso_armas
## Homicidio : 192 :71631 :78992
## Hurto (sin violencia):36159 Con uso de moto: 4588 Arma cortante: 2481
## Lesiones : 6589 Doloso : 84 Arma de fuego: 5917
## Robo (con violencia) :44450 Femicidio : 14
## Hurto Automotor: 3666
## Robo Automotor : 724
## Siniestro Vial : 6683
## barrio comuna latitud longitud
## Palermo : 7785 Min. : 1.000 Min. :-34.70 Min. :-58.53
## Balvanera: 5952 1st Qu.: 4.000 1st Qu.:-34.63 1st Qu.:-58.47
## Flores : 4842 Median : 7.000 Median :-34.61 Median :-58.44
## Recoleta : 4397 Mean : 7.583 Mean :-34.61 Mean :-58.44
## Caballito: 4046 3rd Qu.:12.000 3rd Qu.:-34.59 3rd Qu.:-58.40
## Almagro : 3590 Max. :15.000 Max. :-34.53 Max. :-58.34
## (Other) :56778
## cantidad mes dia_semana
## Min. : 1.00 diciembre: 8521 domingo : 9716
## 1st Qu.: 1.00 noviembre: 8425 lunes :13105
## Median : 1.00 marzo : 7883 martes :13245
## Mean : 1.16 octubre : 7628 miércoles:13253
## 3rd Qu.: 1.00 agosto : 7546 jueves :13177
## Max. :10.00 julio : 7260 viernes :13606
## NA's :80609 (Other) :40127 sábado :11288
Podemos ver que el mes de 2021 en el que más delitos se registraron fue Diciembre y el día de la semana fue el Viernes. Veamos esto en un gráfico:
ggplot(delitos) +
geom_bar(aes(x = mes))
delitos_dia <- delitos %>%
group_by(fecha) %>%
summarise(cantidad=n())
summary(delitos_dia)
## fecha cantidad
## Min. :2021-01-01 Min. : 97.0
## 1st Qu.:2021-04-02 1st Qu.:212.0
## Median :2021-07-02 Median :243.0
## Mean :2021-07-02 Mean :239.4
## 3rd Qu.:2021-10-01 3rd Qu.:270.0
## Max. :2021-12-31 Max. :390.0
Con este resultado, podemos observar que en promedio, durante 2021 ocurrieron 239 delitos por día. Esto se puede ver en el siguiente gráfico de líneas:
ggplot(delitos_dia) +
geom_line(aes(x = fecha, y = cantidad))
Ahora, lo grafico en el mes que mayor delitos se registraron:
Diciembre
ggplot(delitos_dia %>%
filter(month(fecha)==12)) +
geom_line(aes(x = fecha, y = cantidad))+
geom_point(aes(x = fecha, y = cantidad))+
labs(title="EVOLUCIÓN DE DELITOS",
subtitle="Diciembre 2021, CABA",
caption="Elaboración propia en base a datos de BAData")+
theme_minimal()
#### 7.Ahora, agregare una variable más a este análisis, y sera la de
“tipo de delitos”
ggplot(delitos %>%
group_by(fecha, tipo) %>%
summarise(cantidad=n())) +
geom_line(aes(x = fecha, y = cantidad, color=tipo, group=tipo))+
labs(title="DELITOS CABA",
subtitle="AÑO 2021",
caption="Elaboración propia en base a datos de BAData",
color="TIPO",
x="",
y="")+
scale_color_viridis_d(direction=-1)+
scale_x_date(date_breaks = "1 month")+
theme_minimal()+
theme(legend.position="top",
legend.justification = "left",
title=element_text(size=10, face = "bold"),
legend.title=element_text(size=10, face = "bold"),
axis.text.x = element_text(size = 6, angle = 90))
## `summarise()` has grouped output by 'fecha'. You can override using the
## `.groups` argument.
Tal como lo indicó el resumen del principio, está muy claro que el tipo/clase de delito que más se registró fue el Robo (con violencia).
Cabe destacar que, este análisis está sumando la información de todos los meses del año 2021, pero es probable que cada mes tenga sus particularidades, por lo tanto, hice un gráfico separado por mes:
ggplot(delitos)+
geom_bar(aes(x=dia_semana, fill=tipo))+
labs(title="Cantidad de delitos por día y tipo",
subtitle="CABA, Año 2021",
fill="Tipo",
x="Día",
y="Cantidad")+
facet_wrap(~mes)+
theme_minimal()+
theme(axis.text.x = element_text(size = 6, angle = 90),
axis.text.y = element_text(size = 6))
Ya sabemos como ocurrieron los delitos en los dias y meses del año 2021, pero aún no tenemos claro como ocurrió en cada Barrio, por lo tanto, traemos el shape de barrios que tenemos en el proyecto y lo graficamos en el siguiente mapa interactivo:
ggplot()+
geom_sf(data=barrios_caba, color="orange")+
geom_point(data=delitos, aes(x=longitud, y=latitud), size=0.5, alpha=0.4)
delitos_geo <- delitos %>%
st_as_sf(coords = c("longitud", "latitud"), crs = 4326)
ggplot()+
geom_sf(data=barrios_caba)+
geom_sf(data=delitos_geo, aes(color=tipo), alpha=0.3)+
labs(color="Delitos CABA")+
theme_minimal()
Como no todos los datos de nuestor dataset tenian completo el dato “barrio” hicimos un join, y a cada registro se le unió una columna del nombre del barrio con el que se solapa
ggplot()+
geom_sf(data=barrios_caba)+
geom_sf(data=delitos_geo, aes(color=barrio), alpha=0.75, show.legend = FALSE)
Como el objetivo final es mapear los registros de delitos por barrio,
haremos un conteo de delitos por barrio
delitos_barrio <- delitos_geo %>%
group_by(barrio) %>%
summarise(cantidad=n())
delitos_barrio <- delitos_barrio %>%
st_drop_geometry()
Para poder unir ambos dataset, deben tener los campos escritos de la misma forma, por lo tanto, cambie todos los registros a mayuscula, y corregí los acentos que estaban mal escritos.
delitos_barrio <- delitos_barrio %>%
mutate_all(toupper)
correct_tildes <- function(x) {
x <- gsub("á", "A", x)
x <- gsub("é", "E", x)
x <- gsub("Ã", "I", x)
x <- gsub("I³", "O", x)
x <- gsub("ú", "U", x)
x <- gsub("I±", "Ñ", x)
return(x)
}
delitos_barrio <- delitos_barrio %>%
mutate(barrio = correct_tildes(barrio))
Finalmente uni los datos.
barrios_caba <- left_join(barrios_caba, delitos_barrio, by="barrio")
Si bien ya sabemos que el barrio que mas delitos presentó en el 2021 fue Palermo, ahora graficaremos la densidad x km2, de delitos ocurridos en cada barrio
barrios_caba <- barrios_caba %>%
mutate(cantidad = as.numeric(cantidad),
sup_km2 = as.numeric(sup_km2))
ggplot()+
geom_sf(data=barrios_caba, aes(fill=cantidad/sup_km2), color="white")+
labs(title = "Delitos - Cantidad por km2",
subtitle = "Barrios de CABA",
fill = "Cantidad/km2",
caption= "Fuente: Datos Abiertos Gobierno de BsAs - 2021") +
scale_fill_distiller(palette = "YlOrRd", direction = 1) +
theme_minimal()
Por ultimo, y a modo de bonus track, si bien no era requerimiento del TF, quise probar el uso de “Leaflet” con un mapa interactivo:
paleta <- colorNumeric(
palette = "YlOrRd",
domain = barrios_caba$sup_km2)
labels <- sprintf(
"<strong>%s</strong><br/>delitos <br/>%g registros/km2",
barrios_caba$barrio, barrios_caba$sup_km2) %>% lapply(htmltools::HTML)
leaflet(barrios_caba) %>%
addTiles() %>%
addProviderTiles(providers$CartoDB) %>%
addPolygons(color = "#444444",
weight = 1,
smoothFactor = 0.5,
fillOpacity = 0.65,
fillColor = ~colorNumeric("YlOrRd", barrios_caba$sup_km2)(sup_km2),
highlightOptions = highlightOptions(color = "white", weight = 2,
bringToFront = TRUE),
label = labels,
labelOptions = labelOptions(
style = list("font-weight" = "normal", padding = "2px 5px"),
textsize = "10px",
direction = "top"))%>%
addLegend("bottomright", pal=paleta, values = ~sup_km2,
title = "Delitos CABA 2021",
labFormat = labelFormat(suffix = " registros/km2"),
opacity = 0.65)
En resumen, el mapa se muestra coloreado por la cantidad de delitos registrados por kilómetro cuadrado en cada barrio. El mapa es interactivo y permite a los usuarios ver más información sobre cada barrio al hacer clic en él.